package com.scalar.chiptrack.adaptor.sitime;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.utils.ConfigManager;
import com.scalar.chiptrack.users.VendorAdaptor;
import com.scalar.chiptrack.users.dao.AdaptorSetUpDAO;
import com.scalar.ScalarException;
import com.enterprisedt.net.ftp.FTPClient;
import com.enterprisedt.net.ftp.FTPTransferType;
import com.enterprisedt.net.ftp.FTPConnectMode;

import java.util.Calendar;
import java.util.Date;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
import java.net.Socket;
import java.net.SocketException;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 7 Jan, 2010
 * Time: 3:42:06 PM
 */
public class SiTimeFTPAdaptor extends JobHandler implements AdaptorConstants
{

    private static final int    PORT            = 21;
    private static final String FTP_HOST        = "ftp.sitime.net";
    public  static final String ADAPTOR_NAME    = "SITIME_SORT_BIN";
    public static final String FILE_NAME_SORT_WIP = "sitime_sort_bin";
    private static final String FILE_EXTN       = ".txt";

    private String m_username           = null;
    private String m_password           = null;
    private Logger m_adaptorLogger      = null;
    private String m_dataOutputDir      = null;
    private String m_waferMapDir       = null;
    private int    m_adaptor_id         = -1;
    private String fileDate             = null;
    File waferMapFileDir = null;
    private int retryCount = 0;

    public SiTimeFTPAdaptor() throws Exception
    {
        m_waferMapDir = ConfigManager.getReleaseWaferMapFileDir();

        if ( m_waferMapDir != null )
        {
            waferMapFileDir = new File( m_waferMapDir );
            if ( waferMapFileDir.exists() == false )
            {
                waferMapFileDir.mkdirs();
            }
        }

        try
        {
            VendorAdaptor vendorAdaptor = AdaptorSetUpDAO.getVendorAdaptorDetailsByVendorNameAndLocation(VENDOR_NAME_SITIME, WIP_TYPE_SORT );

            m_username = vendorAdaptor.getUserId();
            m_password = vendorAdaptor.getPassWord();
            m_dataOutputDir = vendorAdaptor.getOutPutDirectory();

            if (m_dataOutputDir != null)
            {
                if (m_dataOutputDir.endsWith("/") || m_dataOutputDir.endsWith("\\"))
                {
                    m_dataOutputDir = m_dataOutputDir + m_username;
                }
                else
                {
                    m_dataOutputDir = m_dataOutputDir + "/" + m_username;
                }
            }

            AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
            m_adaptorLogger = AdaptorUtils.getAdaptorLogger(m_dataOutputDir, VENDOR_NAME_SITIME);
            AdaptorUtils.setLogger( m_adaptorLogger );
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading SiTime FTP Adaptor Username, Password details from database, Exception: " + se);
            throw se;
        }
    }

    public static void main( String[] args ) throws Exception
    {
        new SiTimeFTPAdaptor().execute();
    }

    public void execute() throws Exception
    {
        java.util.Date begDate = null;
        try
        {
            //Getting the last Run Adaptor file Date ( As we are Inserting in the new Adaptor run info in the Starting itself)
            fileDate   = AdaptorRunInfo.getAdaptorLastParsedFileDate( ADAPTOR_NAME );

            //When File Date is NULL Setting the File Date Back to 4 Days From Current Date
            if ( fileDate == null )
            {
            	Calendar cal = Calendar.getInstance();
                cal.add( Calendar.DAY_OF_MONTH, -6 );
                begDate = cal.getTime();
                fileDate = StringUtils.formatDateToString( begDate, "MM/dd/yyyy");
            }

            //System.out.println("fileDate = " + fileDate);
            m_adaptor_id = AdaptorRunInfo.saveAdaptorLastUpdatedStatus( CONSTANT_ADAPTOR, ADAPTOR_NAME, CONSTANT_SUCCESS, -1);


            //Print the header details
            AdaptorUtils.printHeader(VENDOR_NAME_SITIME, CONSTANT_ADAPTOR);

            AdaptorUtils.removeOldFiles( m_dataOutputDir, m_adaptorLogger );

            FTPClient ftp = login( FTP_HOST, PORT, m_username, m_password );
            log( "Successfully logged in to " + FTP_HOST );
            System.out.println( "Successfully logged in to " + FTP_HOST );

            ftp.chdir("Jazz_MEMS_wafermaps");
            
            //To Down DownLoad the File To Local System at Specepied path
            downloadSortWIPFiles( ftp );

            // Log out
            logout( ftp );
            log( "\nSuccessfully logged out from SiTime Ftp Site" );
            System.out.println( "\nSuccessfully logged out from SiTime FTP Site" );
        }

        catch ( Exception e )
        {
            //ReLogin
            retryCount ++;
                        
            if (e.toString().indexOf("Connection reset") > -1  && retryCount < 2 )
            {
                AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, m_adaptor_id );
                execute();
            }
            else
            {
                AdaptorUtils.removeOldFiles( m_dataOutputDir, m_adaptorLogger);
                AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, m_adaptor_id );
                System.out.println("Exception while trying to connect and read data from "+FTP_HOST +" site: " + e);
                e.printStackTrace();
                throw e;
            }
        }
    }
    /**
     *
     * @param host
     * @param port
     * @param username
     * @param password
     * @return
     * @throws Exception
     */
    private FTPClient login( String host, int port, String username, String password ) throws Exception
    {
        FTPClient ftp = new FTPClient( host, port );
        ftp.login( username, password );
        ftp.debugResponses( false );
        ftp.setType( FTPTransferType.BINARY );
        // active does not allows me connect to ftp site even any proxy lies in path.
        ftp.setConnectMode( FTPConnectMode.PASV );
        return ftp;
    }

   private void downloadSortWIPFiles( FTPClient ftp ) throws Exception
   	{
	   String[] listings = ftp.dir();

       if ( ( listings == null ) || ( listings.length == 0 ) )
       {
           return;
       }
        File file = null;
        byte[] buf = null;
        String tempFileName     = null;
        Date tempFileDate		= null;
        Date tempmaxDate  		= null;
        FileOutputStream fileOutputStream = null;
        FileOutputStream fileOutputStream1 = null;
           System.out.println("\t\n Downloading the Sort Wafer Map files...... " );
        try
        {
            for ( int i = 0; i < listings.length; i++ )
            {
                if ( listings[i].endsWith( FILE_EXTN_TXT ) )
                {
                    java.util.Date date1 = StringUtils.format( fileDate);
                    java.util.Date date2 = ftp.modtime( listings[i] );
                    
                    if ( date2.compareTo( date1 ) >= 0 )
                    {
                        tempFileDate = date2;
                        if ( tempmaxDate == null )
                        {
                            tempmaxDate = tempFileDate;
                        }
                        else
                        {
                            if ( tempFileDate.compareTo( tempmaxDate ) > 0 )
                            {
                                tempmaxDate = tempFileDate;
                            }
                        }
                        tempFileName = listings[i];
                    }
                }
                if ( fileDate != null && tempFileName != null )
                {
                    log( "\ndownloading file " + tempFileName + " to " + m_dataOutputDir + " directory... " );
                    if ( m_adaptor_id > 0 )
                    {
                        AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , tempFileName.substring(0, tempFileName.indexOf(".") ), FILE_EXTN_TXT, StringUtils.formatDateToString(ftp.modtime(tempFileName), "MM/dd/yyyy HH:mm:ss" ) ) ;
                    }
                    buf = ftp.get( tempFileName );
                    file = new File ( waferMapFileDir.getCanonicalPath (), tempFileName );
                    if ( !file.exists() )
                    {
                        fileOutputStream1 = new FileOutputStream(m_waferMapDir+"/" + tempFileName, false);
                        fileOutputStream1.write( buf );
                        fileOutputStream1.flush();
                    }
                    tempFileName = FILE_NAME_SORT_WIP + "_" + tempFileName.substring(0, tempFileName.indexOf(".") ) + "_" + AdaptorUtils.getTimeAsString() + FILE_EXTN;
                    fileOutputStream = new FileOutputStream( m_dataOutputDir + "/" + tempFileName, false );
                    fileOutputStream.write( buf );
                    fileOutputStream.flush();
                    tempFileName = null;
                }
            }
            
            if ( tempmaxDate != null )
            {
                //To Save the Last Modified date from ftp server
                String maxfileDate = StringUtils.formatDateToString( tempmaxDate,"MM/dd/yyyy");
                log( "maxfileDate = " + maxfileDate );
                AdaptorRunInfo.updateLastRunFileDate( m_adaptor_id , maxfileDate );
            }
        	
        	/*
            java.util.Date maxDate  = null;
            java.util.Date tempmaxDate  = null;
            String tempFileName     = null;

            System.out.println("\tDownloading Sort Bin files....");
            String directoryName = null;
            String subdirectoryName = null;

            // To get the latest maxdate 
            for ( int i = 0; i < directoryListing.length; i++ )
            {
                directoryName = directoryListing[i].substring( directoryListing[i].lastIndexOf( ' ' ) ).trim();
                
                if(  directoryName != null && !directoryName.equalsIgnoreCase( "." )
                        && !directoryName.equalsIgnoreCase( ".." ) && directoryName.startsWith("WaferLot") )
            	{
        			if( "d".equalsIgnoreCase( directoryListing[i].substring( 0, 1 ) ) )
        			{
        				fileDate = fileDate.replaceAll("/","");
                                                
                        java.util.Date date1 = StringUtils.format( fileDate, "MMddyyyy" );
						java.util.Date date2 = getDateFromString( directoryListing[i] );

						if ( date2.compareTo( date1 ) >= 0 )
        				{
                            maxDate = date2;
                            if ( tempmaxDate == null )
                            {
                                tempmaxDate = maxDate;
                            }
                            else
                            {
                                if ( maxDate.compareTo( tempmaxDate ) > 0 )
                                {
                                    tempmaxDate = maxDate;
                                }
                            }

        					log( "Changing to.. " + directoryName );
        					System.out.println( "Changing to.. " + directoryName );

            				ftp.chdir( directoryName + "/SiTime_Probe_Data/" );
            				String[] subdirectoryListings = ftp.dir("",true);
            				for ( int k = 0; k < subdirectoryListings.length; k++ )
                            {
                                subdirectoryName = subdirectoryListings[k].substring( subdirectoryListings[k].lastIndexOf( ' ' ) ).trim();

                                if(  subdirectoryName != null && !subdirectoryName.equalsIgnoreCase( "." )
                                        && !subdirectoryName.equalsIgnoreCase( ".." ) && subdirectoryName.startsWith("Jazz") )
                                {
                                    if( "d".equalsIgnoreCase( directoryListing[i].substring( 0, 1 ) ) )
                                    {
                                        log( "Changing Sub Directory to.. " + subdirectoryName );
        					            //System.out.println( "Changing Sub Directory to.. " + subdirectoryName );
                                        ftp.chdir( subdirectoryName);
                                        String[] fileListings = ftp.dir();

                                        for ( int file = 0; file < fileListings.length; file++ )
                                        {
                                            if ( ( fileListings[file].endsWith( ".txt" )  ) )
                                            {                                                   
                                                tempFileName = fileListings[file];
                                                if ( fileDate != null && tempFileName != null )
                                                {
                                                    log( "\ndownloading file " + tempFileName + " to " + m_dataOutputDir + " directory... " );
                                                    if ( m_adaptor_id > 0 )
                                                    {
                                                        AdaptorRunInfo.saveAdaptorFileInfo( m_adaptor_id , tempFileName.substring(0, tempFileName.indexOf(".") ), FILE_EXTN_TXT, StringUtils.formatDateToString(ftp.modtime(tempFileName), "MM/dd/yyyy HH:mm:ss" ) ) ;
                                                    }
                                                    buf = ftp.get( tempFileName );
                                                    tempFileName = FILE_NAME_SORT_WIP + "_" + tempFileName.substring(0, tempFileName.indexOf(".") ) + "_" + AdaptorUtils.getTimeAsString() + FILE_EXTN;
                                                    fileOutputStream = new FileOutputStream( m_dataOutputDir + "/" + tempFileName, false );
                                                    fileOutputStream.write( buf );
                                                    fileOutputStream.flush();
                                                    tempFileName = null;
                                                }
                                            }

                                        }
                                        ftp.chdir("..");
                                    }
                                }
                            }
            				ftp.chdir( ".." );
            				ftp.chdir( ".." );
                        }
        				else
        				{
        					log( "The dates do not compare" );
        				}
                    }
            	}
            }
            if ( tempmaxDate != null )
            {
                //To Save the Last Modified date from ftp server
                String maxfileDate = StringUtils.formatDateToString( tempmaxDate,"MM/dd/yyyy");
                log( "maxfileDate = " + maxfileDate );
                AdaptorRunInfo.updateLastRunFileDate( m_adaptor_id , maxfileDate );
            }*/
        }
        catch ( Exception e )
        {
            log ("Exception while downloading......... " + e);
            logout( ftp );
            throw e;
        }

        finally
        {
            if ( fileOutputStream != null )
            {
                try
                {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }
                catch ( IOException ignore )
                {
                }
           }
       }
   }

/*
   	private Date getDateFromString( String dirString )
   	{
   		String dateString = null;
        String yearString = null;
        Date dt = null;

   		if( dirString == null || dirString.length() == 0 )
   		{
   			System.out.println( " Dir String is null " );
   			return new Date();
   		}

   		try
		{
            dateString = dirString.substring( ( dirString.indexOf( " WaferLot") - 12 ), dirString.indexOf( " WaferLot" )-5 );
            dateString = dateString.replaceAll( " ", "" );

            //yearString = dirString.substring( ( dirString.indexOf( "0 ") + 8 ), dirString.indexOf( "0 " )  + 14 );

            //yearString = yearString.replaceAll( " ", "" );

            if ( yearString == null || yearString.indexOf(":") != -1 )
            {
                Calendar cal = Calendar.getInstance();
                java.util.Date curDate = cal.getTime();

                yearString = StringUtils.formatDateToString( curDate, "yyyy" );
            }

            dt = StringUtils.format( dateString + yearString , "MMMddyyyy" );

        }
   		catch( Exception e )
		{
   			e.printStackTrace();
   			dt = new Date();
		}

		return dt;
   	}*/
    /**
     *
     * @param ftp
     * @throws Exception
     */
    private void logout( FTPClient ftp ) throws Exception
    {
        if ( ftp == null )
        {
            return;
        }
        try
        {
            ftp.quit();
        }
        catch ( Exception ignore )
        {
            System.out.println( "Exception Occuered While Logging Out From SiTime FTP Site" + ignore );
            throw ignore;
        }
        ftp = null;
    }

    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_adaptorLogger != null )
        {
            synchronized ( m_adaptorLogger )
            {
                m_adaptorLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}
